﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <tchar.h>

HINSTANCE hinstIdLib;
HINSTANCE hinstIcLib;
CVR_InitComm initComm;
CVR_CloseComm closeComm;
CVR_Authenticate authenticate;
CVR_Read_Content read_Content;
GetPeopleName getPeopleName;
GetPeopleIDCode getPeopleIDCode;

rf_init_def rf_init;
rf_exit_def rf_exit;
rf_load_key_def rf_load_key;
rf_card_def rf_card;
rf_read_def rf_read;
rf_authentication_def rf_authentication;
rf_halt_def rf_halt;
rf_beep_def rf_beep;

// add by xyang in 2022.5.9 desc 写卡句柄
rf_write_def rf_write;

bool id_dll_loaded = false;
bool is_id_device_ready = false;

int icdev = 0;
bool ic_dll_loaded = false;
bool is_ic_device_ready = false;

TCHAR dll_base[MAX_PATH] = { 0 };
unsigned char chKey[16] = { 'P', 'U', 'B', '1', '1', 'A', 0x08, 0x77, 0x8F, 0x69, 'B', 'U', 'P', 'Z', 'Y', 'B' };
unsigned char chKey2[16] = { '8', '8', '8', '8', '8', '8', 0x08, 0x77, 0x8F, 0x69, 'Y', 'T', 'A', '9', '8', 'B' };

unsigned char oldChKey[16] = { '8', '8', '8', '8', '8', '8', 0xFF, 0x07, 0x80, 0x69, '8', '8', '8', '8', '8', '8' };

DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
	0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#define   GUID_CLASS_USB_DEVICE                   GUID_DEVINTERFACE_USB_DEVICE  

DEFINE_GUID(GUID_DEVINTERFACE_USB_HUB,
	0xf18a0e88, 0xc30c, 0x11d0, 0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8);
#define		GUID_CLASS_USB_HUB GUID_DEVINTERFACE_USB_HUB


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	TCHAR szBuffer[MAX_PATH] = { 0 };
	TCHAR termbLib[MAX_PATH] = { 0 };
	TCHAR mwrf32Lib[MAX_PATH] = { 0 };
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
		
		GetModuleFileName(hModule, szBuffer, sizeof(szBuffer) / sizeof(TCHAR) - 1);
		_tcsncpy_s(dll_base, szBuffer, (size_t)(_tcslen(szBuffer) - 18));

		_tcscat_s(termbLib, MAX_PATH, dll_base);
		_tcscat_s(termbLib, MAX_PATH, TEXT("Termb.dll"));

		_tcscat_s(mwrf32Lib, MAX_PATH, dll_base);
		_tcscat_s(mwrf32Lib, MAX_PATH, TEXT("MWRF32.dll"));

		hinstIdLib = LoadLibrary(termbLib);
		if (NULL != hinstIdLib) {
			initComm = (CVR_InitComm)GetProcAddress(hinstIdLib, "CVR_InitComm");
			closeComm = (CVR_CloseComm)GetProcAddress(hinstIdLib, "CVR_CloseComm");
			authenticate = (CVR_Authenticate)GetProcAddress(hinstIdLib, "CVR_Authenticate");
			read_Content = (CVR_Read_Content)GetProcAddress(hinstIdLib, "CVR_Read_Content");
			getPeopleName = (GetPeopleName)GetProcAddress(hinstIdLib, "GetPeopleName");
			getPeopleIDCode = (GetPeopleIDCode)GetProcAddress(hinstIdLib, "GetPeopleIDCode");

			id_dll_loaded = true;
			/*
			if (NULL != initComm && initComm(1001) == 1)
				is_id_device_ready = true;
			*/
		}

		hinstIcLib = LoadLibrary(mwrf32Lib);
		if (NULL != hinstIcLib) {
			rf_init = (rf_init_def)GetProcAddress(hinstIcLib, "rf_init");
			rf_exit = (rf_exit_def)GetProcAddress(hinstIcLib, "rf_exit");
			rf_load_key = (rf_load_key_def)GetProcAddress(hinstIcLib, "rf_load_key");
			rf_card = (rf_card_def)GetProcAddress(hinstIcLib, "rf_card");
			rf_read = (rf_read_def)GetProcAddress(hinstIcLib, "rf_read");
			rf_authentication = (rf_authentication_def)GetProcAddress(hinstIcLib, "rf_authentication");
			rf_halt = (rf_halt_def)GetProcAddress(hinstIcLib, "rf_halt");
			rf_beep = (rf_beep_def)GetProcAddress(hinstIcLib, "rf_beep");

			// add by xyang in 2022.5.9 desc 写卡句柄
			rf_write = (rf_write_def)GetProcAddress(hinstIcLib, "rf_write");
			ic_dll_loaded = true;
		}
		break; 
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
		break;
    case DLL_PROCESS_DETACH:
		if (is_id_device_ready && closeComm)
			closeComm();

		if (is_ic_device_ready && rf_exit && icdev >= 0)
			rf_exit(icdev);

		is_id_device_ready = false;
		is_ic_device_ready = false;
		FreeLibrary(hinstIdLib);
		FreeLibrary(hinstIcLib);
		id_dll_loaded = false;
		ic_dll_loaded = false;
        break;
    }
    return TRUE;
}

extern "C" _declspec(dllexport) int ForceReconnect() {
	is_id_device_ready = false;
	is_ic_device_ready = false;

	return 0;
}


extern "C" _declspec(dllexport) int WriteCard(int port, unsigned  char* p8, unsigned  char* p9) {
	int rst = 0;
	unsigned long cid = 0;
	unsigned char chKeyA[6]; 
	unsigned char chKeyB[6];
	if (ic_dll_loaded && NULL != rf_init) {
		if (rf_exit && icdev >= 0)
			rf_exit(icdev);

		icdev = rf_init(port, 9600);
		if (icdev < 0) {
			//9600 连接不上,再用115200尝试连接
			icdev = rf_init(port, 115200);
			if (icdev < 0) {
				//任然连接不上,再返回 -777 连接失败
				return YICT_ERROR_DEVICE_PORT;
			}
		}

		if (sizeof(chKey) == 16) {
			memcpy(chKeyA, chKey2, 6);
			memcpy(chKeyB, &chKey2[10], 6);
											// 2
			rst = rf_load_key(icdev, (short)0, 2, chKeyA);
			if (rst != 0) return YICT_ERROR_LOAD_KEYA;
			rst = rf_load_key(icdev, (short)4, 2, chKeyB);
			if (rst != 0) return YICT_ERROR_LOAD_KEYB;
			rf_beep(icdev, (short)100);
		}
	}

	rf_card(icdev, (short)1, &cid);
	rst = rf_authentication(icdev, 4, 2);
	if (rst == 0) {
		rst = rf_write(icdev, 9, p9);
		if (rst != 0) {
			return YICT_ERROR_WRITE_CARD;
		}
		rst = rf_write(icdev, 8, p8);

		if (rst != 0) {
			return YICT_ERROR_WRITE_CARD;
		}
		return YICT_SUCC_WRITE_CARD;
	}
	else {
		return YICT_ERROR_AUTH;
	}
}

extern "C" _declspec(dllexport) int GetIDCardInfo(int port, char *name, int *name_len, char* idcode, int *idcode_len) {
	int rst = 0;
	if (!is_id_device_ready && id_dll_loaded && NULL != initComm) {
		rst = initComm(port);
		switch (rst) {
		case 1:
			is_id_device_ready = true;
			break;
		case 2:
			return YICT_ERROR_DEVICE_PORT;
		default:
			return YICT_ERROR_DEVICE_PORT;
		}
	}

	if (is_id_device_ready) {
		rst = authenticate();
		switch (rst) {
		case 0:
			return YICT_ERROR_DLL_NOT_FOUND;
		case 1: {
			if (read_Content(1) == 1) {
				getPeopleName(name, name_len);
				getPeopleIDCode(idcode, idcode_len);

				return YICT_SUCC_READ_CARD;
			}
			return YICT_ERROR_READ_CARD;
		}
		case 2:
			return YICT_ERROR_CARD_NOT_FOUND;
		case 3:
			return YICT_ERROR_SELECT_CARD;
		case 4:
			is_id_device_ready = false;
			return YICT_ERROR_DEVICE_PORT;
		default:
			is_id_device_ready = false;
			return YICT_ERROR_UNKNOWN;
		}
	}
	else if (!id_dll_loaded) { return YICT_ERROR_DLL_NOT_FOUND; }
	else { return YICT_ERROR_UNKNOWN; }
}


extern "C" _declspec(dllexport) int ReadCard(int port, char* p8, int* p8_len, char* p9, int* p9_len) {
	int rst = 0;

	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];
	if (ic_dll_loaded && NULL != rf_init) {
		if (rf_exit && icdev >= 0)
			rf_exit(icdev);

		icdev = rf_init(port, 9600);
		if (icdev < 0) {
			//9600 连接不上,再用115200尝试连接
			icdev = rf_init(port, 115200);
			if (icdev < 0) {
				//任然连接不上,再返回 -777 连接失败
				return YICT_ERROR_DEVICE_PORT;
			}
		}

		if (sizeof(chKey) == 16) {
			memcpy(chKeyA, chKey, 6);
			memcpy(chKeyB, &chKey[10], 6);

			// 装载密码的扇区号
			rst = rf_load_key(icdev, (short)0, 1, chKeyA);
			if (rst != 0) return YICT_ERROR_LOAD_KEYA;
			rst = rf_load_key(icdev, (short)4, 1, chKeyB);
			if (rst != 0) return YICT_ERROR_LOAD_KEYB;

			// rf_beep(icdev, (short)100);
		}
	}
	 
	rf_card(icdev, (short)1, &cid);
	// _ultoa_s(cid, card_id, 16, 10);
	// *card_id_len = strlen(card_id);
	// 用 key a的钥匙， 验证2扇区
	rst = rf_authentication(icdev, 0, 1);
	if (rst != 0) {
		// 读 8 块的内容
		//rst = rf_read(icdev, 4, (unsigned char*)p8);
		if (rst != 0) {
			//return YICT_ERROR_READ_CARD;
		}

		rst = rf_read(icdev, 4, (unsigned char*)p9);
		if (rst != 0) {
			return YICT_ERROR_READ_CARD;
		}

		rf_beep(icdev, (short)10);
		*p8_len = strlen(p8); 
		*p9_len = strlen(p9);
		return YICT_SUCC_READ_CARD;
	}
	else {
		return YICT_ERROR_AUTH;
	}
		

	// rf_halt(icdev);
	if (rst == 0) { return YICT_SUCC_READ_CARD; }
	else { return YICT_ERROR_CARD_NOT_FOUND; }
}


extern "C" _declspec(dllexport) int ReadCardHistory(int port, char* p8, int* p8_len, char* p9, int* p9_len) {
	int rst = 0;

	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];
	if (ic_dll_loaded && NULL != rf_init) { 
		if (rf_exit && icdev >= 0)
			rf_exit(icdev);

		icdev = rf_init(port, 9600);
		if (icdev < 0) {
			//9600 连接不上,再用115200尝试连接
			icdev = rf_init(port, 115200);
			if (icdev < 0) {
				//任然连接不上,再返回 -777 连接失败
				return YICT_ERROR_DEVICE_PORT;
			}
		}

		if (sizeof(chKey) == 16) {
			memcpy(chKeyA, chKey2, 6);
			memcpy(chKeyB, &chKey2[10], 6);

			// 装载密码的扇区号
			rst = rf_load_key(icdev, (short)0, 2, chKeyA);
			if (rst != 0) return YICT_ERROR_LOAD_KEYA;
			rst = rf_load_key(icdev, (short)4, 2, chKeyB);
			if (rst != 0) return YICT_ERROR_LOAD_KEYB;

			// rf_beep(icdev, (short)100);
		}
	}

	rf_card(icdev, (short)1, &cid);
	// _ultoa_s(cid, card_id, 16, 10);
	// *card_id_len = strlen(card_id);
	// 用 key a的钥匙， 验证2扇区
	rst = rf_authentication(icdev, 0, 1);
	if (rst == 0) {
		// 读 8 块的内容
		rst = rf_read(icdev, 4, (unsigned char*)p8);
		if (rst != 0) {
			return YICT_ERROR_READ_CARD;
		}

		rst = rf_read(icdev, 9, (unsigned char*)p9);
		if (rst != 0) {
			return YICT_ERROR_READ_CARD;
		}

		rf_beep(icdev, (short)10);
		*p8_len = strlen(p8);
		*p9_len = strlen(p9);
		return YICT_SUCC_READ_CARD;
	}
	else {
		return YICT_ERROR_AUTH;
	}


	// rf_halt(icdev);
	if (rst == 0) { return YICT_SUCC_READ_CARD; }
	else { return YICT_ERROR_CARD_NOT_FOUND; }
}


extern "C" _declspec(dllexport) int GetICCardInfoHistory(int port, char* card_id, int* card_id_len, char* permit_no, int* permit_no_len) {
	int rst = 0;

	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];

	unsigned char oldChKeyA[6];
	unsigned char oldChKeyB[6];
	if (!is_ic_device_ready && ic_dll_loaded && NULL != rf_init) {
		if (rf_exit && icdev >= 0)
			rf_exit(icdev);

		icdev = rf_init(port, 9600);
		if (icdev < 0) {
			//9600 连接不上,再用115200尝试连接
			icdev = rf_init(port, 115200);
			if (icdev < 0) {
				//任然连接不上,再返回 -777 连接失败
				return YICT_ERROR_DEVICE_PORT;
			}
		}

		if (sizeof(chKey) == 16) {
			memcpy(chKeyA, chKey, 6);
			memcpy(chKeyB, &chKey[10], 6);

			rst = rf_load_key(icdev, (short)0, 1, chKeyA);
			if (rst != 0) return YICT_ERROR_LOAD_KEYA;
			rst = rf_load_key(icdev, (short)4, 1, chKeyB);
			if (rst != 0) return YICT_ERROR_LOAD_KEYB;

			rf_beep(icdev, (short)100);
		}
		is_ic_device_ready = true;
	}

	if (is_ic_device_ready) {
		rf_card(icdev, (short)0, &cid);
		_ultoa_s(cid, card_id, 16, 10);
		*card_id_len = strlen(card_id);
		rst = rf_authentication(icdev, 0, 1);
		if (rst != 0) {
			// 重新装载旧密码， 有的读卡器是旧密码， 处理一下旧密码的情况
			memcpy(oldChKeyA, oldChKey, 6);
			memcpy(oldChKeyB, &oldChKey[10], 6);
			rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
			if (rst != 0) return YICT_ERROR_LOAD_KEYA;
			rst = rf_load_key(icdev, (short)4, 1, oldChKeyB);
			if (rst != 0) return YICT_ERROR_LOAD_KEYB;

			rst = rf_authentication(icdev, 0, 1);
			if (rst != 0) {
				// 密码还是不对
				return YICT_ERROR_AUTH;
			}
		}
		rst = rf_read(icdev, 4, (unsigned char*)permit_no);
		if (rst == 0) {
			rf_beep(icdev, (short)10);
			*permit_no_len = strlen(permit_no);
		}
		else if (rst < 0) is_ic_device_ready = false;

		rf_halt(icdev);
		if (rst == 0) { return YICT_SUCC_READ_CARD; }
		else { return rst; }
	}
	else if (!ic_dll_loaded) { return YICT_ERROR_DLL_NOT_FOUND; }
	else { return YICT_ERROR_UNKNOWN; }
}

extern "C" _declspec(dllexport) int GetICCardInfo(int port, char *card_id, int *card_id_len, char* permit_no, int *permit_no_len) {
	int rst = 0;

	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];

	unsigned char oldChKeyA[6];
	unsigned char oldChKeyB[6];
	if (ic_dll_loaded && NULL != rf_init) {
		if (rf_exit && icdev >= 0)
			rf_exit(icdev);

		icdev = rf_init(port, 9600);
		if (icdev < 0) {
			//9600 连接不上,再用115200尝试连接
			icdev = rf_init(port, 115200);
			if (icdev < 0) {
				//任然连接不上,再返回 -777 连接失败
				return YICT_ERROR_DEVICE_PORT;
			}
		}

		if (sizeof(chKey) == 16) {
			memcpy(chKeyA, chKey, 6);
			memcpy(chKeyB, &chKey[10], 6);

			rst = rf_load_key(icdev, (short)0, 1, chKeyA);
			if (rst != 0) return YICT_ERROR_LOAD_KEYA;
			rst = rf_load_key(icdev, (short)4, 1, chKeyB);
			if (rst != 0) return YICT_ERROR_LOAD_KEYB;

		}
	}

	rf_card(icdev, (short)1, &cid);
	_ultoa_s(cid, card_id, 16, 10);
	*card_id_len = strlen(card_id);
	// _ultoa_s(cid, card_id, 16, 10);
	// *card_id_len = strlen(card_id);
	// 用 key a的钥匙， 验证2扇区
	rst = rf_authentication(icdev, 0, 1);
	if (rst != 0) {
		// 重新装载旧密码， 有的读卡器是旧密码， 处理一下旧密码的情况
		memcpy(oldChKeyA, oldChKey, 6);
		memcpy(oldChKeyB, &oldChKey[10], 6);
		rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
		if (rst != 0) return YICT_ERROR_LOAD_KEYA;
		rst = rf_load_key(icdev, (short)4, 1, oldChKeyB);
		if (rst != 0) return YICT_ERROR_LOAD_KEYB;

		rst = rf_authentication(icdev, 0, 1);
		if (rst != 0) {
			// 密码还是不对
			return YICT_ERROR_AUTH;
		}
	}

	// 读 8 块的内容
	rst = rf_read(icdev, 4, (unsigned char*)permit_no);
	if (rst == 0) {
		rf_beep(icdev, (short)10);
		*permit_no_len = strlen(permit_no);
		return YICT_SUCC_READ_CARD;
	} 

	// rf_halt(icdev);
	return YICT_ERROR_CARD_NOT_FOUND;
}

extern "C" _declspec(dllexport) void getDevices(char *devs) {
	//LPGUID lpGuid = (LPGUID)&GUID_CLASS_USB_DEVICE;//
	LPGUID lpGuid = (LPGUID)&GUID_CLASS_USB_HUB;//
	int INTERFACE_DETAIL_SIZE = 1024;
	int nCount = 0;
	HDEVINFO info = SetupDiGetClassDevs(lpGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

	//enumerate device information  
	DWORD required_size = 0;
	int i;
	SP_DEVINFO_DATA DeviceInfoData = { sizeof(DeviceInfoData) };

	DWORD DataT;
	DWORD buffersize = 1024;
	DWORD req_bufsize = 0;

	for (i = 0; SetupDiEnumDeviceInfo(info, i, &DeviceInfoData); i++) {
		WCHAR *did = new WCHAR[1024];
		WCHAR *locid = new WCHAR[1024];
		WCHAR *locdesc = new WCHAR[1024];
		//get device description information
		if (!SetupDiGetDeviceInstanceId(info, &DeviceInfoData, (PTSTR)did, buffersize, &req_bufsize))
			continue;
		if (!SetupDiGetDeviceRegistryPropertyW(info, &DeviceInfoData, SPDRP_LOCATION_PATHS, &DataT, (LPBYTE)locid, buffersize, &req_bufsize))
			continue;

		if (!SetupDiGetDeviceRegistryPropertyW(info, &DeviceInfoData, SPDRP_LOCATION_INFORMATION, &DataT, (LPBYTE)locdesc, buffersize, &req_bufsize))
			continue;
	}

	//strcat(devs, )
	SetupDiDestroyDeviceInfoList(info);
}
